home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / bardock.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  24.2 KB  |  913 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #if !defined(_WIN32_WCE_NO_DOCKBARS)
  13.  
  14. #ifdef AFX_CORE3_SEG
  15. #pragma code_seg(AFX_CORE3_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CDockBar
  27.  
  28. BEGIN_MESSAGE_MAP(CDockBar, CControlBar)
  29.     //{{AFX_MSG_MAP(CDockBar)
  30.     ON_WM_NCCALCSIZE()
  31.     ON_WM_NCPAINT()
  32.     ON_WM_WINDOWPOSCHANGING()
  33.     ON_WM_PAINT()
  34.     ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
  35.     //}}AFX_MSG_MAP
  36. END_MESSAGE_MAP()
  37.  
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CDockBar construction
  40.  
  41. CDockBar::CDockBar(BOOL bFloating)
  42. {
  43.     m_bFloating = bFloating;
  44.     m_bAutoDelete = TRUE;
  45.     m_arrBars.Add(NULL);
  46.     m_bLayoutQuery = FALSE;
  47.     m_rectLayout.SetRectEmpty();
  48.  
  49.     // assume no margins
  50.     m_cxLeftBorder = m_cxRightBorder = m_cyBottomBorder = m_cyTopBorder = 0;
  51. }
  52.  
  53. CDockBar::~CDockBar()
  54. {
  55.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  56.     {
  57.         CControlBar* pBar = GetDockedControlBar(i);
  58.         if (pBar != NULL && pBar->m_pDockBar == this)
  59.             pBar->m_pDockBar = NULL;
  60.     }
  61. }
  62.  
  63. BOOL CDockBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  64. {
  65.     ASSERT(pParentWnd != NULL);
  66.     ASSERT_KINDOF(CFrameWnd, pParentWnd);
  67.  
  68.     // save the style
  69.     m_dwStyle = (dwStyle & CBRS_ALL);
  70.  
  71.     VERIFY(AfxDeferRegisterClass(AFX_WNDCONTROLBAR_REG));
  72.  
  73.     // create the HWND
  74.     CRect rect;
  75.     rect.SetRectEmpty();
  76.  
  77.     // Note: Parent must resize itself for control bar to be resized
  78.     return CWnd::Create(_afxWndControlBar, NULL, dwStyle, rect, pParentWnd, nID);
  79. }
  80.  
  81. BOOL CDockBar::IsDockBar() const
  82. {
  83.     return TRUE;
  84. }
  85.  
  86. int CDockBar::GetDockedCount() const
  87. {
  88.     int nCount = 0;
  89.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  90.     {
  91.         if (GetDockedControlBar(i) != NULL)
  92.             nCount++;
  93.     }
  94.     return nCount;
  95. }
  96.  
  97. int CDockBar::GetDockedVisibleCount() const
  98. {
  99.     int nCount = 0;
  100.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  101.     {
  102.         CControlBar* pBar = STATIC_DOWNCAST(CControlBar, (CObject*)GetDockedControlBar(i));
  103.         if (pBar != NULL && pBar->IsVisible())
  104.             nCount++;
  105.     }
  106.     return nCount;
  107. }
  108.  
  109. /////////////////////////////////////////////////////////////////////////////
  110. // CDockBar operations
  111.  
  112. void CDockBar::DockControlBar(CControlBar* pBar, LPCRECT lpRect)
  113. {
  114.     ASSERT_VALID(this);
  115.     ASSERT_VALID(pBar);
  116.     ASSERT_KINDOF(CControlBar, pBar);
  117.  
  118.     CRect rectBar;
  119.     pBar->GetWindowRect(&rectBar);
  120.     if (pBar->m_pDockBar == this && (lpRect == NULL || rectBar == *lpRect))
  121.     {
  122.         // already docked and no change in position
  123.         return;
  124.     }
  125.  
  126.     // set CBRS_FLOAT_MULTI style if docking bar has it
  127.     if (m_bFloating && (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI))
  128.         m_dwStyle |= CBRS_FLOAT_MULTI;
  129.  
  130.     m_dwStyle &= ~(CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  131.     m_dwStyle |= pBar->m_dwStyle & (CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  132.  
  133.     if (!(m_dwStyle & CBRS_FLOAT_MULTI))
  134.     {
  135.         TCHAR szTitle[_MAX_PATH];
  136.         pBar->GetWindowText(szTitle, _countof(szTitle));
  137.         AfxSetWindowText(m_hWnd, szTitle);
  138.     }
  139.  
  140.     // align correctly and turn on all borders
  141.     DWORD dwStyle = pBar->GetBarStyle();
  142.     dwStyle &= ~(CBRS_ALIGN_ANY);
  143.     dwStyle |=  (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
  144.  
  145.     if (m_bFloating)
  146.         dwStyle |= CBRS_FLOATING;
  147.     else
  148.         dwStyle &= ~CBRS_FLOATING;
  149.  
  150.     pBar->SetBarStyle(dwStyle);
  151.  
  152.     // hide first if changing to a new docking site to avoid flashing
  153.     BOOL bShow = FALSE;
  154.     if (pBar->m_pDockBar != this && pBar->IsWindowVisible())
  155.     {
  156.         pBar->SetWindowPos(NULL, 0, 0, 0, 0,
  157.             SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_HIDEWINDOW);
  158.         bShow = TRUE;
  159.     }
  160.  
  161.     int nPos = -1;
  162.     if (lpRect != NULL)
  163.     {
  164.         // insert into appropriate row
  165.         CRect rect(lpRect);
  166.         ScreenToClient(&rect);
  167.         CPoint ptMid(rect.left + rect.Width()/2, rect.top + rect.Height()/2);
  168.         nPos = Insert(pBar, rect, ptMid);
  169.  
  170.         // position at requested position
  171.         pBar->SetWindowPos(NULL, rect.left, rect.top, rect.Width(),
  172.             rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  173.     }
  174.     else
  175.     {
  176.         // always add on current row, then create new one
  177.         m_arrBars.Add(pBar);
  178.         m_arrBars.Add(NULL);
  179.  
  180.         // align off the edge initially
  181.         pBar->SetWindowPos(NULL, -afxData.cxBorder2, -afxData.cyBorder2, 0, 0,
  182.             SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  183.     }
  184.  
  185.     // attach it to the docking site
  186.     if (pBar->GetParent() != this)
  187.         pBar->SetParent(this);
  188.     if (pBar->m_pDockBar == this)
  189.         pBar->m_pDockBar->RemoveControlBar(pBar, nPos);
  190.     else if (pBar->m_pDockBar != NULL)
  191.         pBar->m_pDockBar->RemoveControlBar(pBar, -1, m_bFloating && !pBar->m_pDockBar->m_bFloating);
  192.     pBar->m_pDockBar = this;
  193.  
  194.     if (bShow)
  195.     {
  196.         ASSERT(!pBar->IsWindowVisible());
  197.         pBar->SetWindowPos(NULL, 0, 0, 0, 0,
  198.             SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);
  199.     }
  200.  
  201.     // remove any place holder for pBar in this dockbar
  202.     RemovePlaceHolder(pBar);
  203.  
  204.     // get parent frame for recalc layout
  205.     CFrameWnd* pFrameWnd = GetDockingFrame();
  206.     pFrameWnd->DelayRecalcLayout();
  207. }
  208.  
  209. void CDockBar::ReDockControlBar(CControlBar* pBar, LPCRECT lpRect)
  210. {
  211.     ASSERT_VALID(this);
  212.     ASSERT_VALID(pBar);
  213.     ASSERT_KINDOF(CControlBar, pBar);
  214.     ASSERT(pBar->m_pDockBar != this); // can't redock here if already docked here
  215.  
  216.     CRect rectBar;
  217.     pBar->GetWindowRect(&rectBar);
  218.     if (pBar->m_pDockBar == this && (lpRect == NULL || rectBar == *lpRect))
  219.     {
  220.         // already docked and no change in position
  221.         return;
  222.     }
  223.  
  224.     // set CBRS_FLOAT_MULTI style if docking bar has it
  225.     if (m_bFloating && (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI))
  226.         m_dwStyle |= CBRS_FLOAT_MULTI;
  227.  
  228.     m_dwStyle &= ~(CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  229.     m_dwStyle |= pBar->m_dwStyle & (CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  230.  
  231.     if (!(m_dwStyle & CBRS_FLOAT_MULTI))
  232.     {
  233.         TCHAR szTitle[_MAX_PATH];
  234.         pBar->GetWindowText(szTitle, _countof(szTitle));
  235.         AfxSetWindowText(m_hWnd, szTitle);
  236.     }
  237.  
  238.     // align correctly and turn on all borders
  239.     DWORD dwStyle = pBar->GetBarStyle();
  240.     dwStyle &= ~(CBRS_ALIGN_ANY);
  241.     dwStyle |=  (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
  242.  
  243.     if (m_bFloating)
  244.         dwStyle |= CBRS_FLOATING;
  245.     else
  246.         dwStyle &= ~CBRS_FLOATING;
  247.  
  248.     pBar->SetBarStyle(dwStyle);
  249.  
  250.     int nPos = FindBar((CControlBar*)_AfxGetDlgCtrlID(pBar->m_hWnd));
  251.     if (nPos > 0)
  252.         m_arrBars[nPos] = pBar;
  253.  
  254.     if (lpRect != NULL)
  255.     {
  256.         CRect rect(lpRect);
  257.         ScreenToClient(&rect);
  258.  
  259.         if (nPos < 1)
  260.         {
  261.             CPoint ptMid(rect.left + rect.Width()/2, rect.top + rect.Height()/2);
  262.             nPos = Insert(pBar, rect, ptMid);
  263.         }
  264.  
  265.         // position at requested position
  266.         pBar->SetWindowPos(NULL, rect.left, rect.top, rect.Width(),
  267.             rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  268.     }
  269.     else
  270.     {
  271.         if (nPos < 1)
  272.         {
  273.             // always add on current row, then create new one
  274.             m_arrBars.Add(pBar);
  275.             m_arrBars.Add(NULL);
  276.         }
  277.  
  278.         // align off the edge initially
  279.         pBar->SetWindowPos(NULL, -afxData.cxBorder2, -afxData.cyBorder2, 0, 0,
  280.             SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  281.     }
  282.  
  283.     // attach it to the docking site
  284.     if (pBar->GetParent() != this)
  285.         pBar->SetParent(this);
  286.     if (pBar->m_pDockBar != NULL)
  287.         pBar->m_pDockBar->RemoveControlBar(pBar);
  288.     pBar->m_pDockBar = this;
  289.  
  290.     // get parent frame for recalc layout
  291.     CFrameWnd* pFrameWnd = GetDockingFrame();
  292.     pFrameWnd->DelayRecalcLayout();
  293. }
  294.  
  295. void CDockBar::RemovePlaceHolder(CControlBar* pBar)
  296. {
  297.     // remove remembered docking position
  298.     if (HIWORD(pBar) != 0)
  299.         pBar = (CControlBar*)_AfxGetDlgCtrlID(pBar->m_hWnd);
  300.     int nOldPos = FindBar(pBar);
  301.     if (nOldPos > 0)
  302.     {
  303.         m_arrBars.RemoveAt(nOldPos);
  304.  
  305.         // remove section indicator (NULL) if nothing else in section
  306.         if (m_arrBars[nOldPos-1] == NULL && m_arrBars[nOldPos] == NULL)
  307.             m_arrBars.RemoveAt(nOldPos);
  308.     }
  309. }
  310.  
  311. BOOL CDockBar::RemoveControlBar(CControlBar* pBar, int nPosExclude, int nAddPlaceHolder)
  312. {
  313.     ASSERT(nAddPlaceHolder == 1 || nAddPlaceHolder == 0 || nAddPlaceHolder == -1);
  314.     ASSERT_VALID(this);
  315.     ASSERT(pBar != NULL);
  316.     int nPos = FindBar(pBar, nPosExclude);
  317.     ASSERT(nPos > 0);
  318.  
  319.     if (nAddPlaceHolder == 1)
  320.     {
  321.         m_arrBars[nPos] = (void*)_AfxGetDlgCtrlID(pBar->m_hWnd);
  322.  
  323.         // check for already existing place holder
  324.         int nPosOld = FindBar((CControlBar*)m_arrBars[nPos], nPos);
  325.         if (nPosOld > 0)
  326.         {
  327.             m_arrBars.RemoveAt(nPos);
  328.  
  329.             // remove section indicator (NULL) if nothing else in section
  330.             if (m_arrBars[nPos-1] == NULL && m_arrBars[nPos] == NULL)
  331.                 m_arrBars.RemoveAt(nPos);
  332.         }
  333.     }
  334.     else
  335.     {
  336.         m_arrBars.RemoveAt(nPos);
  337.         if (m_arrBars[nPos-1] == NULL && m_arrBars[nPos] == NULL)
  338.             m_arrBars.RemoveAt(nPos);
  339.  
  340.         // Remove any pre-existing place holders.
  341.         if (nAddPlaceHolder != -1)
  342.             RemovePlaceHolder(pBar);
  343.     }
  344.  
  345.     // don't do anything more in the shutdown case!
  346.     if (pBar->m_pDockContext == NULL)
  347.         return FALSE;
  348.  
  349.     // get parent frame for recalc layout/frame destroy
  350.     CFrameWnd* pFrameWnd = GetDockingFrame();
  351.     if (m_bFloating && GetDockedVisibleCount() == 0)
  352.     {
  353.         if (GetDockedCount() == 0)
  354.         {
  355.             pFrameWnd->DestroyWindow();
  356.             return TRUE; // Self-Destruct
  357.         }
  358.         else
  359.             pFrameWnd->ShowWindow(SW_HIDE);
  360.     }
  361.     else
  362.         pFrameWnd->DelayRecalcLayout();
  363.  
  364.     return FALSE;
  365. }
  366.  
  367. /////////////////////////////////////////////////////////////////////////////
  368. // CDockBar layout
  369.  
  370. CSize CDockBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  371. {
  372.     ASSERT_VALID(this);
  373.  
  374.     CSize sizeFixed = CControlBar::CalcFixedLayout(bStretch, bHorz);
  375.  
  376.     // get max size
  377.     CSize sizeMax;
  378.     if (!m_rectLayout.IsRectEmpty())
  379.         sizeMax = m_rectLayout.Size();
  380.     else
  381.     {
  382.         CRect rectFrame;
  383.         CFrameWnd* pFrame = GetParentFrame();
  384.         pFrame->GetClientRect(&rectFrame);
  385.         sizeMax = rectFrame.Size();
  386.     }
  387.  
  388.     // prepare for layout
  389.     AFX_SIZEPARENTPARAMS layout;
  390.     layout.hDWP = m_bLayoutQuery ?
  391.         NULL : ::BeginDeferWindowPos(m_arrBars.GetSize());
  392.     CPoint pt(-afxData.cxBorder2, -afxData.cyBorder2);
  393.     int nWidth = 0;
  394.  
  395.     BOOL bWrapped = FALSE;
  396.  
  397.     // layout all the control bars
  398.     for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  399.     {
  400.         CControlBar* pBar = GetDockedControlBar(nPos);
  401.         void* pVoid = m_arrBars[nPos];
  402.  
  403.         if (pBar != NULL)
  404.         {
  405.             if (pBar->IsVisible())
  406.             {
  407.                 // get ideal rect for bar
  408.                 DWORD dwMode = 0;
  409.                 if ((pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) &&
  410.                     (pBar->m_dwStyle & CBRS_FLOATING))
  411.                     dwMode |= LM_HORZ | LM_MRUWIDTH;
  412.                 else if (pBar->m_dwStyle & CBRS_ORIENT_HORZ)
  413.                     dwMode |= LM_HORZ | LM_HORZDOCK;
  414.                 else
  415.                     dwMode |=  LM_VERTDOCK;
  416.  
  417.                 CSize sizeBar = pBar->CalcDynamicLayout(-1, dwMode);
  418.  
  419.                 CRect rect(pt, sizeBar);
  420.  
  421.                 // get current rect for bar
  422.                 CRect rectBar;
  423.                 pBar->GetWindowRect(&rectBar);
  424.                 ScreenToClient(&rectBar);
  425.  
  426.                 if (bHorz)
  427.                 {
  428.                     // Offset Calculated Rect out to Actual
  429.                     if (rectBar.left > rect.left && !m_bFloating)
  430.                         rect.OffsetRect(rectBar.left - rect.left, 0);
  431.  
  432.                     // If ControlBar goes off the right, then right justify
  433.                     if (rect.right > sizeMax.cx && !m_bFloating)
  434.                     {
  435.                         int x = rect.Width() - afxData.cxBorder2;
  436.                         x = max(sizeMax.cx - x, pt.x);
  437.                         rect.OffsetRect(x - rect.left, 0);
  438.                     }
  439.  
  440.                     // If ControlBar has been wrapped, then left justify
  441.                     if (bWrapped)
  442.                     {
  443.                         bWrapped = FALSE;
  444.                         rect.OffsetRect(-(rect.left + afxData.cxBorder2), 0);
  445.                     }
  446.                     // If ControlBar is completely invisible, then wrap it
  447.                     else if ((rect.left >= (sizeMax.cx - afxData.cxBorder2)) &&
  448.                         (nPos > 0) && (m_arrBars[nPos - 1] != NULL))
  449.                     {
  450.                         m_arrBars.InsertAt(nPos, (CObject*)NULL);
  451.                         pBar = NULL; pVoid = NULL;
  452.                         bWrapped = TRUE;
  453.                     }
  454.                     if (!bWrapped)
  455.                     {
  456.                         if (rect != rectBar)
  457.                         {
  458.                             if (!m_bLayoutQuery &&
  459.                                 !(pBar->m_dwStyle & CBRS_FLOATING))
  460.                             {
  461.                                 pBar->m_pDockContext->m_rectMRUDockPos = rect;
  462.                             }
  463.                             AfxRepositionWindow(&layout, pBar->m_hWnd, &rect);
  464.                         }
  465.                         pt.x = rect.left + sizeBar.cx - afxData.cxBorder2;
  466.                         nWidth = max(nWidth, sizeBar.cy);
  467.                     }
  468.                 }
  469.                 else
  470.                 {
  471.                     // Offset Calculated Rect out to Actual
  472.                     if (rectBar.top > rect.top && !m_bFloating)
  473.                         rect.OffsetRect(0, rectBar.top - rect.top);
  474.  
  475.                     // If ControlBar goes off the bottom, then bottom justify
  476.                     if (rect.bottom > sizeMax.cy && !m_bFloating)
  477.                     {
  478.                         int y = rect.Height() - afxData.cyBorder2;
  479.                         y = max(sizeMax.cy - y, pt.y);
  480.                         rect.OffsetRect(0, y - rect.top);
  481.                     }
  482.  
  483.                     // If ControlBar has been wrapped, then top justify
  484.                     if (bWrapped)
  485.                     {
  486.                         bWrapped = FALSE;
  487.                         rect.OffsetRect(0, -(rect.top + afxData.cyBorder2));
  488.                     }
  489.                     // If ControlBar is completely invisible, then wrap it
  490.                     else if ((rect.top >= (sizeMax.cy - afxData.cyBorder2)) &&
  491.                         (nPos > 0) && (m_arrBars[nPos - 1] != NULL))
  492.                     {
  493.                         m_arrBars.InsertAt(nPos, (CObject*)NULL);
  494.                         pBar = NULL; pVoid = NULL;
  495.                         bWrapped = TRUE;
  496.                     }
  497.                     if (!bWrapped)
  498.                     {
  499.                         if (rect != rectBar)
  500.                         {
  501.                             if (!m_bLayoutQuery &&
  502.                                 !(pBar->m_dwStyle & CBRS_FLOATING))
  503.                             {
  504.                                 pBar->m_pDockContext->m_rectMRUDockPos = rect;
  505.                             }
  506.                             AfxRepositionWindow(&layout, pBar->m_hWnd, &rect);
  507.                         }
  508.                         pt.y = rect.top + sizeBar.cy - afxData.cyBorder2;
  509.                         nWidth = max(nWidth, sizeBar.cx);
  510.                     }
  511.                 }
  512.             }
  513.             if (!bWrapped)
  514.             {
  515.                 // handle any delay/show hide for the bar
  516.                 pBar->RecalcDelayShow(&layout);
  517.             }
  518.         }
  519.         if (pBar == NULL && pVoid == NULL && nWidth != 0)
  520.         {
  521.             // end of row because pBar == NULL
  522.             if (bHorz)
  523.             {
  524.                 pt.y += nWidth - afxData.cyBorder2;
  525.                 sizeFixed.cx = max(sizeFixed.cx, pt.x);
  526.                 sizeFixed.cy = max(sizeFixed.cy, pt.y);
  527.                 pt.x = -afxData.cxBorder2;
  528.             }
  529.             else
  530.             {
  531.                 pt.x += nWidth - afxData.cxBorder2;
  532.                 sizeFixed.cx = max(sizeFixed.cx, pt.x);
  533.                 sizeFixed.cy = max(sizeFixed.cy, pt.y);
  534.                 pt.y = -afxData.cyBorder2;
  535.             }
  536.             nWidth = 0;
  537.         }
  538.     }
  539.     if (!m_bLayoutQuery)
  540.     {
  541.         // move and resize all the windows at once!
  542.         if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
  543.             TRACE0("Warning: DeferWindowPos failed - low system resources.\n");
  544.     }
  545.  
  546.     // adjust size for borders on the dock bar itself
  547.     CRect rect;
  548.     rect.SetRectEmpty();
  549.     CalcInsideRect(rect, bHorz);
  550.  
  551.     if ((!bStretch || !bHorz) && sizeFixed.cx != 0)
  552.         sizeFixed.cx += -rect.right + rect.left;
  553.     if ((!bStretch || bHorz) && sizeFixed.cy != 0)
  554.         sizeFixed.cy += -rect.bottom + rect.top;
  555.  
  556.     return sizeFixed;
  557. }
  558.  
  559. LRESULT CDockBar::OnSizeParent(WPARAM wParam, LPARAM lParam)
  560. {
  561.     AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
  562.  
  563.     // set m_bLayoutQuery to TRUE if lpLayout->hDWP == NULL
  564.     BOOL bLayoutQuery = m_bLayoutQuery;
  565.     CRect rectLayout = m_rectLayout;
  566.     m_bLayoutQuery = (lpLayout->hDWP == NULL);
  567.     m_rectLayout = lpLayout->rect;
  568.     LRESULT lResult = CControlBar::OnSizeParent(wParam, lParam);
  569.     // restore m_bLayoutQuery
  570.     m_bLayoutQuery = bLayoutQuery;
  571.     m_rectLayout = rectLayout;
  572.  
  573.     return lResult;
  574. }
  575.  
  576. /////////////////////////////////////////////////////////////////////////////
  577. // CDockBar message handlers
  578.  
  579. void CDockBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
  580. {
  581.     // calculate border space (will add to top/bottom, subtract from right/bottom)
  582.     CRect rect;
  583.     rect.SetRectEmpty();
  584.     CalcInsideRect(rect, m_dwStyle & CBRS_ORIENT_HORZ);
  585.  
  586.     // adjust non-client area for border space
  587.     lpncsp->rgrc[0].left += rect.left;
  588.     lpncsp->rgrc[0].top += rect.top;
  589.     lpncsp->rgrc[0].right += rect.right;
  590.     lpncsp->rgrc[0].bottom += rect.bottom;
  591. }
  592.  
  593. void CDockBar::OnNcPaint()
  594. {
  595.     EraseNonClient();
  596. }
  597.  
  598. void CDockBar::DoPaint(CDC*)
  599. {
  600.     // border painting is done in non-client area
  601. }
  602.  
  603. void CDockBar::OnPaint()
  604. {
  605.     // background is already filled in gray
  606.     CPaintDC dc(this);
  607.     if (IsVisible() && GetDockedVisibleCount() != 0)
  608.         DoPaint(&dc);       // delegate to paint helper
  609. }
  610.  
  611. void CDockBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
  612. {
  613.     // not necessary to invalidate the borders
  614.     DWORD dwStyle = m_dwStyle;
  615.     m_dwStyle &= ~(CBRS_BORDER_ANY);
  616.     CControlBar::OnWindowPosChanging(lpWndPos);
  617.     m_dwStyle = dwStyle;
  618. }
  619.  
  620. /////////////////////////////////////////////////////////////////////////////
  621. // CDockBar utility/implementation
  622.  
  623. int CDockBar::FindBar(CControlBar* pBar, int nPosExclude)
  624. {
  625.     for (int nPos = 0; nPos< m_arrBars.GetSize(); nPos++)
  626.     {
  627.         if (nPos != nPosExclude && m_arrBars[nPos] == pBar)
  628.             return nPos;
  629.     }
  630.     return -1;
  631. }
  632.  
  633. void CDockBar::ShowAll(BOOL bShow)
  634. {
  635.     for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  636.     {
  637.         CControlBar* pBar = GetDockedControlBar(nPos);
  638.         if (pBar != NULL)
  639.         {
  640.             CFrameWnd* pFrameWnd = pBar->GetDockingFrame();
  641.             pFrameWnd->ShowControlBar(pBar, bShow, TRUE);
  642.         }
  643.     }
  644. }
  645.  
  646. CControlBar* CDockBar::GetDockedControlBar(int nPos) const
  647. {
  648.     CControlBar* pResult = (CControlBar*)m_arrBars[nPos];
  649.     if (HIWORD(pResult) == 0)
  650.         return NULL;
  651.     return pResult;
  652. }
  653.  
  654. int CDockBar::Insert(CControlBar* pBarIns, CRect rect, CPoint ptMid)
  655. {
  656.     ASSERT_VALID(this);
  657.     ASSERT(pBarIns != NULL);
  658.  
  659.     int nPos = 0;
  660.     int nPosInsAfter = 0;
  661.     int nWidth = 0;
  662.     int nTotalWidth = 0;
  663.     BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ;
  664.  
  665.     for (nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  666.     {
  667.         CControlBar* pBar = GetDockedControlBar(nPos);
  668.         if (pBar != NULL && pBar->IsVisible())
  669.         {
  670.             CRect rectBar;
  671.             pBar->GetWindowRect(&rectBar);
  672.             ScreenToClient(&rectBar);
  673.             nWidth = max(nWidth,
  674.                 bHorz ? rectBar.Size().cy : rectBar.Size().cx - 1);
  675.             if (bHorz ? rect.left > rectBar.left : rect.top > rectBar.top)
  676.                 nPosInsAfter = nPos;
  677.         }
  678.         else // end of row because pBar == NULL
  679.         {
  680.             nTotalWidth += nWidth - afxData.cyBorder2;
  681.             nWidth = 0;
  682.             if ((bHorz ? ptMid.y : ptMid.x) < nTotalWidth)
  683.             {
  684.                 if (nPos == 0) // first section
  685.                     m_arrBars.InsertAt(nPosInsAfter+1, (CObject*)NULL);
  686.                 m_arrBars.InsertAt(nPosInsAfter+1, pBarIns);
  687.                 return nPosInsAfter+1;
  688.             }
  689.             nPosInsAfter = nPos;
  690.         }
  691.     }
  692.  
  693.     // create a new row
  694.     m_arrBars.InsertAt(nPosInsAfter+1, (CObject*)NULL);
  695.     m_arrBars.InsertAt(nPosInsAfter+1, pBarIns);
  696.  
  697.     return nPosInsAfter+1;
  698. }
  699.  
  700. void CDockBar::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNoHndler*/)
  701. {
  702. }
  703.  
  704. #ifdef _DEBUG
  705. void CDockBar::AssertValid() const
  706. {
  707.     CControlBar::AssertValid();
  708.     ASSERT(m_arrBars.GetSize() != 0);
  709.     ASSERT(m_arrBars[0] == NULL);
  710.     ASSERT(m_arrBars[m_arrBars.GetUpperBound()] == NULL);
  711. }
  712.  
  713. void CDockBar::Dump(CDumpContext& dc) const
  714. {
  715.     CControlBar::Dump(dc);
  716.  
  717.     dc << "m_arrBars " << m_arrBars;
  718.     dc << "\nm_bFloating " << m_bFloating;
  719.  
  720.     dc << "\n";
  721. }
  722. #endif
  723.  
  724. /////////////////////////////////////////////////////////////////////////////
  725. // CControlBar docking helpers
  726.  
  727. void CControlBar::EnableDocking(DWORD dwDockStyle)
  728. {
  729.     // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  730.     ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  731.     // CBRS_SIZE_DYNAMIC toolbar cannot have the CBRS_FLOAT_MULTI style
  732.     ASSERT(((dwDockStyle & CBRS_FLOAT_MULTI) == 0) || ((m_dwStyle & CBRS_SIZE_DYNAMIC) == 0));
  733.  
  734.     m_dwDockStyle = dwDockStyle;
  735.     if (m_pDockContext == NULL)
  736.         m_pDockContext = new CDockContext(this);
  737.  
  738.     // permanently wire the bar's owner to its current parent
  739.     if (m_hWndOwner == NULL)
  740.         m_hWndOwner = ::GetParent(m_hWnd);
  741. }
  742.  
  743. /////////////////////////////////////////////////////////////////////////////
  744. // CMiniDockFrameWnd
  745.  
  746. BEGIN_MESSAGE_MAP(CMiniDockFrameWnd, CMiniFrameWnd)
  747.     //{{AFX_MSG_MAP(CMiniDockFrameWnd)
  748.     ON_WM_CLOSE()
  749.     ON_WM_NCLBUTTONDOWN()
  750.     ON_WM_NCLBUTTONDBLCLK()
  751.     //}}AFX_MSG_MAP
  752.     ON_WM_MOUSEACTIVATE()
  753. END_MESSAGE_MAP()
  754.  
  755. int CMiniDockFrameWnd::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
  756. {
  757.     if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST) // resizing
  758.         return MA_NOACTIVATE;
  759.     return CMiniFrameWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
  760. }
  761.  
  762. CMiniDockFrameWnd::CMiniDockFrameWnd() : m_wndDockBar(TRUE)
  763. {
  764.     m_wndDockBar.m_bAutoDelete = FALSE;
  765. }
  766.  
  767. BOOL CMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
  768. {
  769.     // set m_bInRecalcLayout to avoid flashing during creation
  770.     // RecalcLayout will be called once something is docked
  771.     m_bInRecalcLayout = TRUE;
  772.  
  773.     DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
  774.         MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
  775.         FWS_SNAPTOBARS;
  776.  
  777.     if (dwBarStyle & CBRS_SIZE_DYNAMIC)
  778.         dwStyle &= ~MFS_MOVEFRAME;
  779.  
  780.     DWORD dwExStyle = 0;
  781.     if (!CMiniFrameWnd::CreateEx(dwExStyle,
  782.         NULL, &afxChNil, dwStyle, rectDefault, pParent))
  783.     {
  784.         m_bInRecalcLayout = FALSE;
  785.         return FALSE;
  786.     }
  787.     dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
  788.         CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
  789.     dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;
  790.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  791.     pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
  792.     pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
  793.     pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
  794.     pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
  795.     CString strHide;
  796.     if (strHide.LoadString(AFX_IDS_HIDE))
  797.     {
  798.         pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
  799.         pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
  800.     }
  801.  
  802.     // must initially create with parent frame as parent
  803.     if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
  804.         AFX_IDW_DOCKBAR_FLOAT))
  805.     {
  806.         m_bInRecalcLayout = FALSE;
  807.         return FALSE;
  808.     }
  809.  
  810.     // set parent to CMiniDockFrameWnd
  811.     m_wndDockBar.SetParent(this);
  812.     m_bInRecalcLayout = FALSE;
  813.  
  814.     return TRUE;
  815. }
  816.  
  817. void CMiniDockFrameWnd::RecalcLayout(BOOL bNotify)
  818. {
  819.     if (!m_bInRecalcLayout)
  820.     {
  821.         CMiniFrameWnd::RecalcLayout(bNotify);
  822.  
  823.         // syncronize window text of frame window with dockbar itself
  824.         TCHAR szTitle[_MAX_PATH];
  825.         m_wndDockBar.GetWindowText(szTitle, _countof(szTitle));
  826.         AfxSetWindowText(m_hWnd, szTitle);
  827.     }
  828. }
  829.  
  830. void CMiniDockFrameWnd::OnClose()
  831. {
  832.     m_wndDockBar.ShowAll(FALSE);
  833. }
  834.  
  835. void CMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
  836. {
  837.     if (nHitTest == HTCAPTION)
  838.     {
  839.         // special activation for floating toolbars
  840.         ActivateTopParent();
  841.  
  842.         // initiate toolbar drag for non-CBRS_FLOAT_MULTI toolbars
  843.         if ((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0)
  844.         {
  845.             int nPos = 1;
  846.             CControlBar* pBar = NULL;
  847.             while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
  848.                 pBar = m_wndDockBar.GetDockedControlBar(nPos++);
  849.  
  850.             ASSERT(pBar != NULL);
  851.             ASSERT_KINDOF(CControlBar, pBar);
  852.             ASSERT(pBar->m_pDockContext != NULL);
  853.             pBar->m_pDockContext->StartDrag(point);
  854.             return;
  855.         }
  856.     }
  857.     else if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST)
  858.     {
  859.         // special activation for floating toolbars
  860.         ActivateTopParent();
  861.  
  862.         int nPos = 1;
  863.         CControlBar* pBar = NULL;
  864.         while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
  865.             pBar = m_wndDockBar.GetDockedControlBar(nPos++);
  866.  
  867.         ASSERT(pBar != NULL);
  868.         ASSERT_KINDOF(CControlBar, pBar);
  869.         ASSERT(pBar->m_pDockContext != NULL);
  870.  
  871.         // CBRS_SIZE_DYNAMIC toolbars cannot have the CBRS_FLOAT_MULTI style
  872.         ASSERT((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0);
  873.         pBar->m_pDockContext->StartResize(nHitTest, point);
  874.         return;
  875.     }
  876.     CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
  877. }
  878.  
  879. void CMiniDockFrameWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
  880. {
  881.     if (nHitTest == HTCAPTION)
  882.     {
  883.         // special activation for floating toolbars
  884.         ActivateTopParent();
  885.  
  886.         // initiate toolbar toggle for non-CBRS_FLOAT_MULTI toolbars
  887.         if ((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0)
  888.         {
  889.             int nPos = 1;
  890.             CControlBar* pBar = NULL;
  891.             while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
  892.                 pBar = m_wndDockBar.GetDockedControlBar(nPos++);
  893.  
  894.             ASSERT(pBar != NULL);
  895.             ASSERT_KINDOF(CControlBar, pBar);
  896.             ASSERT(pBar->m_pDockContext != NULL);
  897.             pBar->m_pDockContext->ToggleDocking();
  898.             return;
  899.         }
  900.     }
  901.     CMiniFrameWnd::OnNcLButtonDblClk(nHitTest, point);
  902. }
  903.  
  904. #ifdef AFX_INIT_SEG
  905. #pragma code_seg(AFX_INIT_SEG)
  906. #endif
  907.  
  908. IMPLEMENT_DYNAMIC(CDockBar, CControlBar)
  909. IMPLEMENT_DYNCREATE(CMiniDockFrameWnd, CMiniFrameWnd)
  910.  
  911. /////////////////////////////////////////////////////////////////////////////
  912. #endif // _WIN32_WCE_NO_DOCKBARS
  913.